Started onThursday, 2 September 2021, 2:16 PM
StateFinished
Completed onWednesday, 15 September 2021, 8:12 AM
Time taken12 days 17 hours
GradeNot yet graded

Question 1

Complete
Marked out of 15.00
Flag question

Question text

Processes

Useful resources

http://www.gnu.org/software/libc/manual/html_mono/libc.html#Processes

Answer the following Questions:

  1. What are the return values from the fork() function from the point of view of the parent and child process?
  2. What function is used to get the ID of a process?
  3. What function is used to get the ID of the parent process?
  4. What is a process image?
  5. What happens to the original process image when exec() is called?
  6. What are the differences among the family of exec() functions?
  7. Explain the id_t waitpid (pid_t pid, int *status-ptr, int options) function
  8. Explain the pid_t wait (int *status-ptr) function
  9. Explain its difference with waitpid()

1) pid_t fork(void) returns the pid of the child for a parent fork and for a child fork it returns 0. Any error yields -1.

2) pid_t getpid(void) returns the pid of the current process.

3) pid_t getppid(void) returns the pid of the parent process.

4) The process image is everything you get from the program executable and load into memory, plus everything that gets added or modified at load time. The address space is all its virtual addresses, and whatever is in them.

5) It gets replaced with the new requested process from the exec function call.

6) The exec function has the following versions or family:

(A thing to note is that the functions in this family differ in how you specify the arguments, but otherwise they all do the same thing. They are declared in the header file unistd.h.)

- int execv -> Executes the file named by filename as a new process image.

- int execl -> Similar to execv, but the argv string are specified individually instead of as an array. A null pointer must be passed as the last such argument.

- int execve -> This is similar to execv, but permits you to specify the environment for the new program explicitly as the env argument. This should be an array of strings in the same format as for the environ variable.

- int fexecve -> This is similar to execve, but instead of identifying the program executable by its pathname, the file descriptor fd is used. The descriptor must have been opened with the O_RDONLY flag or (on Linux) the O_PATH flag.

- int execle -> This is similar to execl, but permits you to specify the environment for the new program explicitly. The environment argument is passed following the null pointer that marks the last argv argument, and should be an array of strings in the same format as for the environ variable.

- int execvp -> The execvp function is similar to execv, except that it searches the directories listed in the PATH environment variable to find the full file name of a file from filename if filename does not contain a slash. This function is useful for executing system utility programs, because it looks for them in the places that the user has chosen. Shells use it to run the commands that users type.

- int execlp -> This function is like execl, except that it performs the same file name searching as the execvp function.

7) The pid_t waitpid (pid_t pid, int *status-ptr, int options) function is used to request status information from a child process whose process ID is pid. Normally, the calling process is suspended until the child process makes status information available by terminating. If status information for a child process is available immediately, this function returns immediately without waiting. If more than one eligible child process has status information available, one of them is chosen randomly, and its status is returned immediately. To get the status from the other eligible child processes, you need to call the function again. The status information from the child process is stored in the object that status-ptr points to, unless status-ptr is a null pointer. The return value is normally the process ID of the child process whose status is reported. If there are child processes but none of them is waiting to be noticed, waitpid will block until one is. However, if the WNOHANG option was specified, waitpid will return zero instead of blocking. A value of -1 is returned in case of error.

8) The pid_t wait (int *status-ptr) function is a simplified version of waitpid, and is used to wait until any one child process terminates. This function can be used a cancellation point in multi-threaded programs. This is a problem if the thread allocates some resources (like memory, file descriptors, semaphores or whatever) at the time wait is called. If the thread gets canceled these resources stay allocated until the program ends. To avoid this calls to wait should be protected using cancellation handlers.

9) The difference lies in the fact that waitpid waits for the requested pid child to terminate, on-the-other-hand, wait resumes execution immediately after any of the child processes terminates.

Question 2

Complete
Marked out of 8.00
Flag question

Question text

Based on the following code:


/* Example of use of fork system call */
#include <stdio.h>
main()
{
  int pid;  
  pid = fork();
  if (pid < 0) {
fprintf(stderr, "Fork failed!\n");
exit(-1);
  }
  else if (pid==0) {
      execlp("/bin/ps", "ps", NULL);
      printf("Still around...\n");
  }
  else {
exit(0);
  }
}

Describe what the program does, and identify its parts. Distinguish between the code executed by each process (parent and child).


The following code describes the use of the fork() function call.

If the function yields -1 then this means that the fork failed and thus we see the "Forked fail" print statement followed by Exit(-1).

Else if the function yields 0 this means that the pid we are referencing is a child process that was just created. In this particular code if a child is created, a system call (execlp) is invoked to replace the current process image with a new one and the objective of this new image is to execute the file "pm" found in the directory "/bin/pm"

Finally in the else statement the code enters the parent process and exits the code successfully.

Question 3

Complete
Marked out of 15.00
Flag question

Question text

Based on the code from the previous question:

  1. Modify the program so the parent process waits for the child process to end before exiting.
  2. Modify the program so the child process displays its own process id and the process id of its parent
  3. Modify the program so the parent process displays the process id of its child. 

Paste your (final) modified code bellow.


/* Example of use of fork system call */
#include <stdio.h>
void main()
{
int pid;
pid = fork();

if (pid < 0) //error
{
fprintf(stderr, "Fork failed!\n"); exit(-1);
}
else if (pid==0) // child
{
execlp("/bin/ps", "ps", NULL);
printf("Still around...\n");
}
else // parent
{
// display its own pid and the ppid:
printf( "Child PID: %d\n Parent PID: %d\n\n", pid, (int)getpid() );
// parent waits for the child process end before continuing
int wait_pid = waitpid(pid);
if( wait_pid < 0) printf( "Error while waiting for child!\n" );
else printf( "Child's PID: %d\n\n", pid ); // display pid

exit(0); // exit succesfully
}
}

Question 4

Complete
Marked out of 8.00
Flag question

Question text

Based on your modified code from previous question, why is the "Still around" message not displayed?

The "still around" message is not displayed because when the system calls "execlp" and is executed, the child terminates the process and does not get to the print line because of the NULL pointer in the parameter.

Question 5

Correct
Mark 54.00 out of 54.00
Flag question

Question text

Using the system() function, develop a C program that downloads (using wget) this file: https://www.c-programming-simple-steps.com/support-files/return-statement.zip.
Use the necessary flag of the wget command to hide the errors/warnings/logs from the download. Then use the ls | grep command to list the files that start with the name return



(penalty regime: 0 %)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char command[300];
//copy the command to download the file
//execute the command
strcpy(command,"wget -q https://www.c-programming-simple-steps.com/support-files/return-statement.zip");
system(command);
//copy the commmand to list the files
//execute the command
strcpy(command, "ls|grep return");
system(command);
return(0);
}
 

Feedback